package 线程同步.研究所;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: FCHL
 * @Description:
 * @Date: 09:36 2021/4/15
 * @Modified By:
 **/
public class ThreadSync {
    final TargetTest tt = new TargetTest();


    public static void main(String[] args) {
        ThreadSync ts = new ThreadSync();
//        ts.unSync();
        ts.mqSync();
    }


    /**
     * 使用消息同步
     */
    private void mqSync() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
        executor.execute(() -> {
            int num = 100;
            while (true) {
                try {
                    if (tt.getCount() > num * 10) {
                        System.out.println("wait sub");
                        Thread.sleep(2000);
                    } else {
                        tt.add(num);
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                }
            }
        });
        executor.execute(() -> {
            int num = 100;
            while (true) {
                try {
                    if (tt.getCount() < num) {
                        System.out.println("wait add");
                        Thread.sleep(3000);
                    } else {
                        tt.sub(num);
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 线程未同步，会出现不够减的情况
     */
    private void unSync() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
        executor.execute(() -> {
            int num = 100;
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                tt.add(num);

            }
        });
        executor.execute(() -> {
            int num = 100;
            while (true) {
                tt.sub(num);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

class TargetTest {

    private int count = 0;

    public void add(int num) {
        count += num;
        System.out.println(System.currentTimeMillis() + " add：" + num + " count：" + count);
    }

    public void sub(int num) {
        if (count - num < 0) {
            System.out.println("总数不足");
            return;
        }
        count -= num;
        System.out.println(+System.currentTimeMillis() + " sub：" + num + " count：" + count);
    }


    public int getCount() {
        return count;
    }
}